use std::collections::{HashMap};
use crate::db::dao::im_module_dao::{module_inserts, module_item_inserts, module_item_updates, module_total, module_updates, query_module_items_by_id_and_name, query_modules_by_names};
use crate::db::db::Db;
use crate::db::db_transaction::transaction;
use crate::db::pojo::pojo::{ImModule};

pub struct ImModuleService;

impl ImModuleService {

    pub fn save_modules(&self, modules: &mut Vec<ImModule>) {
        let db = Db::open();
        transaction(db.clone(), move |db: Db| {
            self.save_modules_business(db, modules)
        });
    }

    pub fn total(&self)->usize {
        let db = Db::open();
        let total = transaction(db.clone(), move |db: Db| {
            module_total(db)
        });
        total
    }

    fn save_modules_business(&self, db: Db, modules: &mut Vec<ImModule>) {
        let module_codes = modules.iter().map(|module| {module.name.clone()}).collect::<Vec<String>>();
        log::info!("db module codes: {:?}", module_codes);
        let db_modules = query_modules_by_names(db.clone(), module_codes);
        log::info!("db groups: {:?}", db_modules);
        let db_modules = db_modules.into_iter().map(|module| {(module.name.clone(), module)}).collect::<HashMap<_, _>>();

        let mut insert_modules= Vec::new();
        let mut update_modules = Vec::new();
        let mut insert_module_items= Vec::new();
        let mut update_module_items = Vec::new();

        for module in modules.iter_mut() {
            let db_module = db_modules.get(module.name.as_str());
            match db_module {
                None => {
                    insert_modules.push(module);

                }
                Some(db_module) => {
                    module.id = db_module.id.clone();
                    let module_items_option = (&module.module_items).clone();
                    if let Some(module_items) = module_items_option {
                        for mut module_item in module_items.into_iter() {
                            let db_module_item = query_module_items_by_id_and_name(db.clone(), db_module.id.clone().unwrap(), module_item.name.clone());
                            match db_module_item {
                                None => {
                                    insert_module_items.push(module_item);
                                }
                                Some(_db_module_item ) => {
                                    module_item.module_id = db_module.id.clone();
                                    update_module_items.push(module_item);
                                }
                            }
                        }
                    }
                    update_modules.push(module);
                }
            }
        }

        module_inserts(db.clone(), &mut insert_modules);
        module_updates(db.clone(), &mut update_modules);

        module_item_inserts(db.clone(), &mut insert_module_items);
        module_item_updates(db.clone(), &mut update_module_items);
    }
}
